package com.uhu.tag.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.uhu.common.UtagConstant;
import com.uhu.exception.BusinessException;
import com.uhu.redis.RedisKeyConstant;
import com.uhu.tag.dao.TagMapper;
import com.uhu.tag.dto.req.TagSaveReqDTO;
import com.uhu.tag.dto.req.TagUpdateReqDTO;
import com.uhu.tag.dto.res.TagListByTagGroupIdResDTO;
import com.uhu.tag.entity.Tag;
import com.uhu.tag.service.ITagService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * <p>
 * 标签表 服务实现类
 * </p>
 *
 * @author liujunjie
 * @since 2023-12-12
 */
@Slf4j
@Service
public class TagServiceImpl extends ServiceImpl<TagMapper, Tag> implements ITagService {

    @Autowired
    private RedissonClient redissonClient;

    @Override
    public List<TagListByTagGroupIdResDTO> tagListQueryByTagGroupId(Long tagGroupId) {
        List<Tag> tags = list(new QueryWrapper<Tag>().eq("tag_group_id", tagGroupId));
        return BeanUtil.copyToList(tags, TagListByTagGroupIdResDTO.class);
    }

    @Override
    public void saveTag(TagSaveReqDTO tagSaveReqDTO) {
        RLock rLock = redissonClient.getLock(RedisKeyConstant.TAG_EDIT_LOCK);
        if (!rLock.tryLock()) {
            throw new BusinessException(UtagConstant.GET_LOCK_FAIL);
        }

        try {
            Tag tag = getOne(new QueryWrapper<Tag>().eq("tag_group_id", tagSaveReqDTO.getTagGroupId()).orderByAsc("sort_id").last("limit 1"));
            Integer lastSortId = 0;
            if (tag != null) {
                lastSortId = tag.getSortId() + 1;
            }
            Tag saveTag = BeanUtil.copyProperties(tagSaveReqDTO, Tag.class);
            saveTag.setSortId(lastSortId);
            saveOrUpdate(saveTag);
        } finally {
            rLock.unlock();
        }
    }

    @Override
    public void updateTag(TagUpdateReqDTO tagUpdateReqDTO) {
        RLock rLock = redissonClient.getLock(RedisKeyConstant.TAG_EDIT_LOCK);
        if (!rLock.tryLock()) {
            throw new BusinessException(UtagConstant.GET_LOCK_FAIL);
        }

        try {
            long count = count(new QueryWrapper<Tag>().eq("tag_id", tagUpdateReqDTO.getTagId()));
            if (count < 1) {
                throw new BusinessException("标签不存在");
            }
            saveOrUpdate(BeanUtil.copyProperties(tagUpdateReqDTO, Tag.class));
        } finally {
            rLock.unlock();
        }
    }

    @Override
    public void sortTag(Long[] ids, Long tagGroupId) {
        RLock rLock = redissonClient.getLock(RedisKeyConstant.TAG_EDIT_LOCK);
        if (!rLock.tryLock()) {
            throw new BusinessException(UtagConstant.GET_LOCK_FAIL);
        }

        try {
            // 统计标签组下标签数
            long count = count(new QueryWrapper<Tag>().eq("tag_group_id", tagGroupId).in("tag_id", ids));
            if (count != ids.length) {
                log.error("sortTag ids.length != database.size, please check it");
                throw new BusinessException(UtagConstant.SYSTEM_ERROR);
            }
            for (int i = 0; i < ids.length; i++) {
                Tag tag = new Tag();
                tag.setTagId(ids[i]);
                tag.setTagGroupId(tagGroupId);
                tag.setSortId(i);
                updateById(tag);
            }
        } finally {
            rLock.unlock();
        }
    }

    @Override
    public void deleteTag(Long tagId) {
        RLock rLock = redissonClient.getLock(RedisKeyConstant.TAG_EDIT_LOCK);
        if (!rLock.tryLock()) {
            throw new BusinessException(UtagConstant.GET_LOCK_FAIL);
        }

        try {
            Long size = count(new QueryWrapper<Tag>().eq("tag_id", tagId).last("limit 1"));
            if (size < 1) {
                log.error("deleteTag tagId = {} not found", tagId);
                throw new BusinessException(UtagConstant.SYSTEM_ERROR);
            }

            String username = "xx";
            if (!username.equals("admin")) {
                throw new BusinessException("无权限，无法删除！！！");
            }

            removeById(tagId);
        } finally {
            rLock.unlock();
        }
    }
}
